package population;

import java.util.logging.Logger;

import character.race.RaceProperties;
import population.phaseExecutors.AgePhase;
import population.phaseExecutors.CompositePhase;
import population.phaseExecutors.FindLovePhase;
import population.phaseExecutors.MarryPhase;
import population.phaseExecutors.PhaseExecutor;
import utilities.WorldState;

/**
 * Main generator class.
 * @author pcdejager
 */
public final class Generator {
    /**
     * Run.
     * @param days The number of days to simulate
     */
    public void run(final int days) {
        // Pipeline
        LOGGER.info("Creating generator pipeline");
        GeneratorPipeline pipe = new GeneratorPipeline();
        pipe.addExecutor(new AgePhase(1));
        pipe.addExecutor(createFindLovePhases());
        pipe.addExecutor(createMarryPhases());
        // TODO : Add phase executors
        // Populations
        LOGGER.info("Creating initial populations");
        Population p = generateInitialPopulations();
        // TODO : Setup exit conditions
        int dayCount = 0;
        while (dayCount < days) {
            LOGGER.info("Date: " + WorldState.getState().now().toString());
            pipe.execute(p);
            ++dayCount;
        }
        LOGGER.info("Generation complete");
    }

    /**
     * Generate initial populations.
     * @return The populations
     */
    private Population generateInitialPopulations() {
        InitialPopulationGenerator p = new InitialPopulationGenerator();
        return p.generate();
    }

    /**
     * Create the find love phases as a composite phase.
     * @return The phase
     */
    private PhaseExecutor createFindLovePhases() {
        CompositePhase phase = new CompositePhase();
        String[] races = RaceProperties.getInstance().getRaces();
        for (int count = 0; count < races.length; ++count) {
            phase.addPhase(new FindLovePhase(races[count]));
        }
        return phase;
    }

    /**
     * Create the marry pases as a composite phase.
     * @return The phase
     */
    private PhaseExecutor createMarryPhases() {
        CompositePhase phase = new CompositePhase();
        String[] races = RaceProperties.getInstance().getRaces();
        for (int count = 0; count < races.length; ++count) {
            phase.addPhase(new MarryPhase(races[count]));
        }
        return phase;
    }

    /**
     * Logger.
     */
    private static final Logger LOGGER =
            Logger.getLogger(Generator.class.getName());
}
